#ifndef __COMMAND_H__
#define __COMMAND_H__

#include "membackend/accurateAddressMappingConfig.h"
#include "membackend/accurateTransaction.h"

typedef enum class CommandType
{
    READ = 0,
    WRITE,
    REFRESH,
    ACTIVATE,
    PRECHARGE,
    INVALID
} CommandType;


class DRAMCommand
{
public:

    uint64_t trans_id;
    CommandType type;
    uint64_t address;
    uint64_t bank_id;
    uint64_t rank_id;
    uint64_t bank_group_id;
    uint64_t row_id; // Optional, if needed for specific commands
    uint64_t column_id; // Optional, if needed for specific commands

    DRAMCommand();
    DRAMCommand(uint64_t trans_id, CommandType type, uint64_t address, uint64_t bank_id, uint64_t rank_id, uint64_t bank_group_id, uint64_t row_id, uint64_t column_id);
    uint64_t getTransId() const { return trans_id; }
};

typedef struct Command{
    CommandType type;
    uint64_t address;
    uint64_t bank_id;
    uint64_t rank_id;
    uint64_t bank_group_id;
    uint64_t row_id; // Optional, if needed for specific commands
    uint64_t column_id; // Optional, if needed for specific commands
}Command;



class CommandQueue
{
private:
    std::vector<std::vector<DRAMCommand>> queue;
    MyQueuePolicy queue_policy;
    uint64_t cmd_queue_delay;

public:

    CommandQueue();
    CommandQueue(AddressMappingConfig *amp);
    bool WillAcceptCommand(uint64_t rank_id, uint64_t bank_group_id, uint64_t bank_id);
    bool AddCommand(DRAMCommand cmd);
    DRAMCommand GetCommand(uint64_t rank_id, uint64_t bank_group_id, uint64_t bank_id);
    uint64_t Process(Transaction &trans, uint64_t time);
    uint64_t Process(DRAMCommand cmd, uint64_t time);
    DRAMCommand Trans2CMD(Transaction &trans);
    bool isEmpty();
    void DeleteCommand(uint64_t rank_id, uint64_t bank_group_id, uint64_t bank_id, uint64_t id);
};






#endif